﻿// -------------------------------------------------------------------------
//    @FileName         :    IAction.cpp
//    @Author           :    gaoyi
//    @Date             :    24-8-1
//    @Email            :    445267987@qq.com
//    @Module           :    IAction
//
// -------------------------------------------------------------------------

#include "IAction.h"

#if NF_PLATFORM == NF_PLATFORM_WIN
#else
#include <netinet/in.h>
#endif
#include <NFComm/NFPluginModule/NFCheck.h>
#include <NFLogicCommon/CustomPacketParse.h>
#include "GameApi.h"
#include "ProtoUtil.h"

int IAction::Exec()
{
	CHECK_NULL(0, m_pGameAPI);

	int iRet = MakePacket();
	CHECK_RET(iRet, "make packet failed!");

	bool bIsEnd     = false;
	int  iRecvCount = 0;
	while (iRecvCount < 1000)
	{
		int iRecvLen = m_pGameAPI->Recv(m_pGameAPI->m_szRecvBuf.WriteAddr(), m_pGameAPI->m_szRecvBuf.WritableSize());
		CHECK_EXPR(iRecvLen >= 0, -1, "gamesvr recv error!");

		if (iRecvLen > 0)
			NFLogDebug(NF_LOG_DEFAULT, 0, "recv msg len:{}", iRecvLen);

		++iRecvCount;
		m_pGameAPI->m_szRecvBuf.Produce(iRecvLen);

		if (ProtoUtil::IsPacketComplete(m_pGameAPI->m_szRecvBuf.ReadAddr(), m_pGameAPI->m_szRecvBuf.ReadableSize()))
		{
			int                             iHeadLen = 0;
			int                             iPackLen = 0;
			proto_client2access::C2AMsgHead oMsgHead;
			iRet = ProtoUtil::UnpackC2AHead(m_pGameAPI->m_szRecvBuf.ReadAddr(), m_pGameAPI->m_szRecvBuf.ReadableSize(), oMsgHead, iHeadLen, iPackLen);
			CHECK_RET(iRet, "unpack c2a head failed!");

			NFLogDebug(NF_LOG_DEFAULT, 0, "recv complete packet!msg id::{} headlen:{} packet len:{}", (int)oMsgHead.cmd(), iHeadLen, iPackLen);

			char* pData    = m_pGameAPI->m_szRecvBuf.ReadAddr() + MSG_HEAD_LEN + iHeadLen;
			int   iDataLen = iPackLen - MSG_HEAD_LEN - iHeadLen;
			iRet           = HandlePacket(oMsgHead, pData, iDataLen, bIsEnd);

			m_pGameAPI->m_szRecvBuf.Consume(iPackLen);

			if (bIsEnd)
			{
				break;
			}
		}
	}

	if (!bIsEnd)
	{
		NFLogError(NF_LOG_DEFAULT, 0, "--error 999--!");
		return -999;
	}

	return iRet;
}

int IAction::HandlePacket(proto_client2access::C2AMsgHead& oMsgHead, char* pData, int iDataLen, bool& bIsEnd)
{
	bIsEnd = false;
	switch (oMsgHead.cmd())
	{
		case proto_client2access::E_A2C_TRANSFERDATA:
		{
			CSS2CPkgHead& stPkgHead = *((CSS2CPkgHead *)pData);
			stPkgHead.m_iDataLen    = ntohl(stPkgHead.m_iDataLen);
			stPkgHead.m_wCmd        = ntohs(stPkgHead.m_wCmd);
			stPkgHead.m_wSeq        = ntohs(stPkgHead.m_wSeq);

			int iLen = sizeof(CSS2CPkgHead) + stPkgHead.m_iDataLen;

			NFLogDebug(NF_LOG_DEFAULT, 0, "recv cs packet!msg id:{} datalen:{} packet len:{} total len:{}", (int)stPkgHead.m_wCmd, iDataLen, stPkgHead.m_iDataLen, iLen);

			proto_ff::Proto_CSRsp oCSRsp;
			bool                  bOk = oCSRsp.ParseFromArray(pData+sizeof(stPkgHead), stPkgHead.m_iDataLen);
			CHECK_EXPR(bOk, -1, "parse cs rsp failed!");

			m_pGameAPI->HandleCSPacket(stPkgHead.m_wCmd, oCSRsp);

			int iRetCode = HandleCSPacket(stPkgHead.m_wCmd, oCSRsp, bIsEnd);
			CHECK_RET(iRetCode, "handle cs packet failed! retcode:{}", iRetCode);
			break;
		}
		default:
		{
			return -1;
		}
	}

	return 0;
}
